package jmine.selenium;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;

import bancosys.tec.services.junitx.IntegrationTestSuite;

/**
 * Test Suite utilizada pelos Test Runners de Selenium
 * 
 * @author Rafael Volpato
 * @date Dec 3, 2010
 */
public class SeleniumTestRunnerTestSuite extends IntegrationTestSuite {

    /**
     * Construtor
     * 
     * @param <T> Tipo do teste de selenium
     * @param clazz classe do teste de selenium
     * @param baseTestLocation arquivo de teste que deve ser utilizado
     * @param configuration configuração de execução do teste
     */
    public <T extends SeleniumTestCase> SeleniumTestRunnerTestSuite(Class<T> clazz, String baseTestLocation,
            EnvironmentConfiguration configuration) {
        super();

        Constructor<T> constructorURL;
        T testCase;

        URL urlBaseTestLocation = null;
        try {
            urlBaseTestLocation = new File(baseTestLocation.trim()).toURI().toURL();
        } catch (MalformedURLException e1) {
            this.addTest(warning("O endereço/arquivo " + baseTestLocation + " é inválido!"));
            return;
        }

        if (!SeleniumTestCase.class.isAssignableFrom(clazz)) {
            this.addTest(warning("Class " + clazz.getName() + " does not extend the superclass SeleniumTestCase"));
            return;
        }

        // Configurar o ambiente de testes
        SeleniumTestCase.setConfiguration(configuration);

        try {
            constructorURL = clazz.getConstructor(new Class[]{ URL.class });
        } catch (NoSuchMethodException e) {
            this.addTest(warning("Class " + clazz.getName() + " has no public constructor TestCase(URL)"));
            return;
        }

        if (!Modifier.isPublic(clazz.getModifiers())) {
            this.addTest(warning("Class " + clazz.getName() + " is not public"));
            return;
        }

        try {
            testCase = constructorURL.newInstance(new Object[]{ urlBaseTestLocation });
            this.createTestCases(constructorURL, testCase);
        } catch (Exception e) {
            e.printStackTrace();
            this.addTest(warning("Could not create new instance of " + clazz.getName() + ", " + e.getMessage()));
            return;
        }

        if (this.testCount() == 0) {
            this.addTest(warning("No tests found in " + clazz.getName()));
        }
    }
}
